package net.wofly.sale.order.service.impl;

import net.wofly.common.condition.Condition;
import net.wofly.common.condition.ConditionRelate;
import net.wofly.common.condition.ConditionUtil;
import net.wofly.common.condition.FilterCondition;
import net.wofly.common.condition.Operation;
import net.wofly.common.json.XiNiaoJSON;
import net.wofly.common.persistence.PageWrapper;
import net.wofly.common.util.CalcUtil;
import net.wofly.common.util.GeneralHelper;
import net.wofly.common.util.Identities;
import net.wofly.common.util.PageHelper;
import net.wofly.framework.util.ResultCode;
import net.wofly.framework.util.ReturnBean;
import net.wofly.right.domain.User;
import net.wofly.right.service.IUserService;
import net.wofly.sale.activity.domain.Activity;
import net.wofly.sale.activity.domain.ActivityGift;
import net.wofly.sale.activity.service.IActivityService;
import net.wofly.sale.commodity.domain.Commodity;
import net.wofly.sale.commodity.domain.CommodityChannel;
import net.wofly.sale.commodity.domain.CommodityTerminal;
import net.wofly.sale.commodity.service.ICommodityChannelService;
import net.wofly.sale.commodity.service.ICommodityService;
import net.wofly.sale.commodity.service.ICommodityTmlService;
import net.wofly.sale.order.domain.Gift;
import net.wofly.sale.order.domain.Order;
import net.wofly.sale.order.domain.OrderContent;
import net.wofly.sale.order.domain.OrderPublishActivityMapping;
import net.wofly.sale.order.domain.ReturnGift;
import net.wofly.sale.order.domain.ReturnSales;
import net.wofly.sale.order.domain.ReturnSalesContent;
import net.wofly.sale.order.repository.ReturnSalesRepository;
import net.wofly.sale.order.service.IOrderPublishActivityMappingService;
import net.wofly.sale.order.service.IReturnGiftService;
import net.wofly.sale.order.service.IReturnSalesContentService;
import net.wofly.sale.order.service.IReturnSalesService;
import net.wofly.sale.order.service.ISaleOrderService;
import net.wofly.sale.order.util.OrderStatus;
import net.wofly.sale.order.util.OrderType;
import net.wofly.sale.order.util.OrderUtil;
import net.wofly.sale.order.util.ReturnSalesStatus;
import net.wofly.sale.stock.domain.InOutStockDetail;
import net.wofly.sale.stock.domain.InStock;
import net.wofly.sale.stock.service.IStockService;
import net.wofly.sale.stock.util.InStockType;
import org.apache.commons.collections.CollectionUtils;
import org.joda.time.LocalDate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Service("iReturnSalesService")
@Transactional
public class ReturnSalesServiceImpl implements IReturnSalesService {
    
    Logger logger = LoggerFactory.getLogger(ReturnSalesServiceImpl.class);
    
    @Autowired
    ReturnSalesRepository returnSalesRepository;
    @Autowired
    IReturnSalesContentService iReturnSalesContentService;
    @Autowired
    IReturnGiftService iReturnGiftService;
    @Autowired
    IUserService iUserService;
    @Autowired
    ISaleOrderService iSaleOrderService;
    @Autowired
    private ICommodityService iCommodityService;
    @Autowired
    private ICommodityTmlService iCommodityTmlService;
    @Autowired
    private ICommodityChannelService iCommodityChannelService;
    @Autowired
    private IActivityService iActivityService;
    @Autowired
    private IOrderPublishActivityMappingService iOrderPublishActivityMappingService;
    @Autowired
    private IStockService iStockService;
    
    @Override
    public ReturnSales save(ReturnSales entity) {
        return returnSalesRepository.save(entity);
    }
    
    @Override
    public void delete(ReturnSales entity) {
        returnSalesRepository.delete(entity);
    }
    
    @Override
    public void delete(String key) {
        returnSalesRepository.delete(key);
    }
    
    @Override
    public ReturnSales findOne(String key) {
        return returnSalesRepository.findOne(key);
    }
    
    @Override
    public Page<ReturnSales> findAll(Specification specification, Pageable pageable) {
        return returnSalesRepository.findAll(specification, pageable);
    }
    
    @Override
    public List<ReturnSales> save(List<ReturnSales> entityList) {
        return (List<ReturnSales>) returnSalesRepository.save(entityList);
    }
    
    @Override
    public Integer countByOrderIDAndStatusNotIn(String orderID, List<Integer> statusList) {
        return returnSalesRepository.countByOrderIDAndStatusNotIn(orderID, statusList);
    }
    
    @Override
    public Object findMaxReturnSalesNONoByDate(String dateStr) {
        return returnSalesRepository.findMaxReturnSalesNONoByDate(dateStr);
    }
    
    @Override
    public ReturnSales transReturnSales(ReturnSales returnSales) {
        if (null != returnSales.getStatus()) {
            returnSales.setStatusStr(ReturnSalesStatus.getName(returnSales.getStatus()));
        }
        
        User user = iUserService.findOne(returnSales.getReturner());
        if (null != returnSales.getReturner()) {
            returnSales.setReturnUserName(user.getName());
            returnSales.setReturnUser(user);
        }
        
        returnSales.setStatus(returnSales.getStatus());
        
        List<ReturnGift> returnGifts = iReturnGiftService.findByReturnSalesID(returnSales.getReturnSalesID());
        
        returnSales.setReturnGifts(returnGifts);
        
        return returnSales;
    }
    
    @Override
    public ReturnSales findByProcessInsID(String processInsID) {
        return returnSalesRepository.findByProcessInsID(processInsID);
    }
    
    @Override
    public List<ReturnSales> findByProcessInsIDIn(List<String> processInsIDs) {
        return returnSalesRepository.findByProcessInsIDIn(processInsIDs);
    }
    
    @Override
    public String generateReturnSalesNO() {
        String returnSalesNo;
        String dateStr = LocalDate.now().toString("yyyyMMdd");
        Object maxOrderNoByDate = findMaxReturnSalesNONoByDate(dateStr);
        if (!StringUtils.isEmpty(maxOrderNoByDate)) {
            Long newReturnSalesNo = Long.valueOf(dateStr + maxOrderNoByDate.toString()) + 1;
            returnSalesNo = String.valueOf(newReturnSalesNo);
        } else {
            returnSalesNo = dateStr + "0001";
        }
        return returnSalesNo;
    }
    
    @Override
    public ReturnBean<ReturnSales> getBackGoodsForReturnSales(String orderID) {
        Order order = iSaleOrderService.findOne(orderID);
        if (order == null) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单ID不正确");
        }
        //未支付的订单不能申请退货
        if (OrderStatus.订单提交_未支付.getValue().intValue() == order.getStatus()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "未支付的订单不能申请退货");
        }
        
        ReturnSales returnSales = new ReturnSales();
        returnSales.setOrderID(order.getOrderID());
        returnSales.setCustomerUserID(order.getCustomerUserID());
        returnSales.setReturner(order.getBuyer());
        returnSales.setOrderNo(order.getOrderNo());
        returnSales.setOrderTypeStr(OrderType.getName(order.getOrderType()));
        
        //转换为退货内容
        List<ReturnSalesContent> returnSalesContents = new ArrayList<>();
        for (OrderContent orderContent : order.getOrderContents()) {
            ReturnSalesContent returnSalesContent = new ReturnSalesContent();
            returnSalesContent.setOrderContentID(orderContent.getOrderContentID());
            returnSalesContent.setCommodityChannelID(orderContent.getCommodityChannelID());
            CommodityChannel commodityChannel = iCommodityChannelService.findOne(orderContent.getCommodityChannelID());
            buildReturnSalesContentCommodityInfo(returnSalesContent, commodityChannel);
            returnSalesContent.setMaxReturnNum(orderContent.getNum());
            returnSalesContent.setInitialTotalPrice(orderContent.getTotalPrice());
            returnSalesContent.setNum(0);
            returnSalesContent.setPrice(orderContent.getPrice());
            returnSalesContent.setTotalPrice(orderContent.getPrice() * returnSalesContent.getNum());
            
            //处理退货内容的赠品信息
            List<Gift> gifts = orderContent.getGifts();
            if (CollectionUtils.isNotEmpty(gifts)) {
                List<ReturnGift> returnGifts = new ArrayList<>();
                for (Gift gift : gifts) {
                    ReturnGift returnGift = new ReturnGift();
                    returnGift.setNum(0);
                    returnGift.setMaxReturnNum(gift.getNum());
                    returnGift.setGiftID(gift.getGiftID());
                    returnGift.setCommodityTerminalID(gift.getCommodityTerminalID());
                    Commodity commodity = iCommodityTmlService.findCommodityByCommodityTerminalID(
                            gift.getCommodityTerminalID());
                    returnGift.setCommodity(commodity);
                    returnGifts.add(returnGift);
                }
                returnSalesContent.setReturnGifts(returnGifts);
            }
            returnSalesContents.add(returnSalesContent);
        }
        returnSales.setReturnSalesContents(returnSalesContents);
        
        //转换为退货订单的赠品信息
        List<Gift> orderGifts = order.getGifts();
        if (CollectionUtils.isNotEmpty(orderGifts)) {
            List<ReturnGift> returnGifts = new ArrayList<>();
            for (Gift orderGift : orderGifts) {
                ReturnGift returnGift = new ReturnGift();
                returnGift.setGiftID(orderGift.getGiftID());
                returnGift.setMaxReturnNum(orderGift.getNum());
                returnGift.setNum(0);
                returnGift.setCommodityTerminalID(orderGift.getCommodityTerminalID());
                Commodity commodity = iCommodityTmlService.findCommodityByCommodityTerminalID(
                        orderGift.getCommodityTerminalID());
                returnGift.setCommodity(commodity);
                returnGifts.add(returnGift);
            }
            returnSales.setReturnGifts(returnGifts);
        }
        return new ReturnBean<>(ResultCode.SUCCESS, "查询成功", returnSales);
    }
    
    private void buildReturnSalesContentCommodityInfo(
            ReturnSalesContent returnSalesContent, CommodityChannel commodityChannel) {
        if (commodityChannel == null) {
            logger.info("商品渠道ID为空，不能查询到对应的商品详情");
        } else {
            ReturnBean<Commodity> commodityReturnBean = iCommodityService.getCommodityChannelByID(
                    commodityChannel.getCommodityID());
            if (commodityReturnBean.getCode() == 0) {
                returnSalesContent.setCommodity(commodityReturnBean.getResult());
            }
        }
    }
    
    /**
     * 退货预计算
     *
     * @param orderID
     * @param returnSales
     * @return
     */
    @Override
    public ReturnBean<ReturnSales> preCalcReturnSales(String orderID, ReturnSales returnSales) {
        //查询订单
        Order order = iSaleOrderService.findOne(orderID);
        ReturnBean<ReturnSales> errorResult = validateInitOrderInfo(order);
        if (errorResult != null) {
            return errorResult;
        }
        
        returnSales.setReturnGifts(null);
        
        ReturnBean<ReturnSales> returnSalesReturnBean = calcReturnSalesInfo(returnSales, order);
        if (ResultCode.SUCCESS.intValue() == returnSalesReturnBean.getCode()) {
            translateReturnSalesInfo(returnSalesReturnBean.getResult());
        }
        
        return returnSalesReturnBean;
    }
    
    private ReturnBean<ReturnSales> validateReturnSalesInfo(Order order) {
        ReturnBean<ReturnSales> x = validateInitOrderInfo(order);
        if (x != null) {
            return x;
        }

        // 已经申请过退货的订单不能再次进行退货
        List<Integer> statusList = Arrays.asList(ReturnSalesStatus.取消.getValue());
        Integer count = countByOrderIDAndStatusNotIn(order.getOrderID(), statusList);
        if (count != null && count > 0) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单已经申请退货（只能退货一次），不能重复申请");
        }
        return null;
    }

    private ReturnBean<ReturnSales> validateInitOrderInfo(Order order) {
        if (order == null) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单ID不正确");
        }
        //未支付的订单不能申请退货
        if (OrderStatus.订单提交_未支付.getValue().intValue() == order.getStatus()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "未支付的订单不能申请退货");
        }
        return null;
    }

    private ReturnBean<ReturnSales> calcReturnSalesInfo(ReturnSales returnSales, Order order) {
        // 满3赠1  购买9 赠3
        // 退正品6 退赠品2，
        // 退正品5 退赠品2，
        // 退正品4 退赠品2，
        // 退正品3 退赠品1，
        
        //原订单中商品与赠品的映射关系
        Map<String, List<Gift>> orderContentIDAndGiftMapping = new HashMap<>();
        // 订单内容ID与订单内容的映射关系
        Map<String, OrderContent> orderContentIDAndOrderContentMapping = new HashMap<>();
        //退货数量校验，不能超过下单时的商品和赠品数量的上限
        Map<String, Integer> maxReturnNumMap = new HashMap<>();
        
        for (OrderContent orderContent : order.getOrderContents()) {
            maxReturnNumMap.put(orderContent.getOrderContentID(), orderContent.getNum());
            orderContentIDAndOrderContentMapping.put(orderContent.getOrderContentID(), orderContent);
            if (CollectionUtils.isNotEmpty(orderContent.getGifts())) {
                orderContentIDAndGiftMapping.put(orderContent.getOrderContentID(), orderContent.getGifts());
            }
        }
        String returnSalesID;
        if (StringUtils.isEmpty(returnSales.getReturnSalesID())) {
            returnSalesID = Identities.uuid2();
            returnSales.setReturnSalesID(returnSalesID);
        } else {
            returnSalesID = returnSales.getReturnSalesID();
        }
        
        long modifyDate = System.currentTimeMillis();
        returnSales.setModifyDate(modifyDate);
        returnSales.setReturnSalesTime(modifyDate);
        
        int totalCommodityNum = 0;
        int totalGiftNum = 0;
        Double orderTotalReturnPrice = 0.0;
        
        //  根据渠道价格计算退货的款项
        //根据退货数量和活动信息计算退货的赠品信息， 两部分：1 订单内容赠品的退回； 2 订单赠品的退回， 需要先计算订单商品的，后计算订单赠品的
        //1 订单内容赠品的退回
        //处理退货商品及商品的赠品信息
        if (CollectionUtils.isNotEmpty(returnSales.getReturnSalesContents())) {
            for (ReturnSalesContent returnSalesContent : returnSales.getReturnSalesContents()) {
                if (null == maxReturnNumMap.get(returnSalesContent.getOrderContentID())) {
                    return new ReturnBean<>(ResultCode.ERROR_SERVICE, "退货的returnSalesContentID不正确，请检查");
                }
                //退货数量校验，不能超过下单时的商品和赠品数量的上限
                if (returnSalesContent.getNum() > maxReturnNumMap.get(returnSalesContent.getOrderContentID())
                        || returnSalesContent.getNum() < 0) {
                    return new ReturnBean<>(ResultCode.ERROR_SERVICE, "退货数量不正确，请检查");
                }
                returnSalesContent.setReturnGifts(null);
                returnSalesContent.setReturnSalesID(returnSalesID);
                returnSalesContent.setReturnSalesContentID(Identities.uuid2());
                //下单时的订单内容
                OrderContent initOrderContent = orderContentIDAndOrderContentMapping.get(
                        returnSalesContent.getOrderContentID());
                Double price = initOrderContent.getPrice();
                returnSalesContent.setTotalPrice(price * returnSalesContent.getNum());
                returnSalesContent.setPrice(price);
                orderTotalReturnPrice = orderTotalReturnPrice + returnSalesContent.getTotalPrice();
                returnSalesContent.setMaxReturnNum(initOrderContent.getNum());
                returnSalesContent.setInitialTotalPrice(initOrderContent.getTotalPrice());
                returnSalesContent.setModifyDate(modifyDate);
                
                totalCommodityNum = totalCommodityNum + returnSalesContent.getNum();
                if (orderContentIDAndGiftMapping.containsKey(returnSalesContent.getOrderContentID())) {
                    if (returnSalesContent.getNum() == 0) {
                        //相当于不退
                        continue;
                    } else {
                        List<Gift> gifts = orderContentIDAndGiftMapping.get(returnSalesContent.getOrderContentID());
                        String activityID = gifts.get(0).getActivityID();
                        Activity activity = iActivityService.findOne(activityID);
                        //退货后享受活动的次数
                        int afterBackGiftTimes = new BigDecimal(
                                Math.floor(
                                        (initOrderContent.getNum() - returnSalesContent.getNum()) / activity.getNum()
                                )).intValue();
                        List<ReturnGift> returnGifts = new ArrayList<>();
                        for (Gift gift : gifts) {
                            ReturnGift returnGift = new ReturnGift();
                            returnGift.setReturnGiftID(Identities.uuid2());
                            returnGift.setGiftID(gift.getGiftID());
                            returnGift.setMaxReturnNum(gift.getNum());
                            returnGift.setModifyDate(modifyDate);
                            returnGift.setCommodityTerminalID(gift.getCommodityTerminalID());
                            returnGift.setReturnSalesContentID(returnSalesContent.getReturnSalesContentID());
                            //returnGift.setReturnSalesID(returnSales.getReturnSalesID());
                            //退回的赠品数量=原来赠品的数量减去本次退货后剩下订单内容可以得到赠品的数量
                            //订单内容原始享受每满赠的次数
                            int initPerGiftTimes = new BigDecimal(
                                    Math.floor(
                                            initOrderContent.getNum() / activity.getNum())).intValue();
                            //原始活动的一份赠品数量（activityGift 表中的num）,此处一定可以整除
                            int perGiftNum = gift.getNum() / initPerGiftTimes;
                            returnGift.setNum(gift.getNum() - (perGiftNum * afterBackGiftTimes));
                            totalGiftNum = totalGiftNum + returnGift.getNum();
                            returnGifts.add(returnGift);
                        }
                        returnSalesContent.setReturnGifts(returnGifts);
                    }
                }
            }
        }
        
        //2 订单赠品的退回
        List<Gift> orderGifts = order.getGifts();
        if (CollectionUtils.isNotEmpty(orderGifts)) {
            if (orderTotalReturnPrice != 0) {
                //退货后真实订单的价格
                Double realBuyedPrice = CalcUtil.sub(order.getRealPrice(), orderTotalReturnPrice);
                List<OrderPublishActivityMapping> orderPublishActivityMappings = iOrderPublishActivityMappingService
                        .findByOrderID(order.getOrderID());
                List<String> actvityIDs = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(orderPublishActivityMappings)) {
                    for (OrderPublishActivityMapping orderPublishActivityMapping : orderPublishActivityMappings) {
                        actvityIDs.add(orderPublishActivityMapping.getActivityID());
                    }
                    Activity realActivity = null;
                    List<Activity> activities = iActivityService.findByActivityIDIn(actvityIDs);
                    for (Activity activity : activities) {
                        if (activity.getStartAmount() <= realBuyedPrice && realBuyedPrice < activity.getEndAmount()) {
                            //只能满足一个订单赠品的活动
                            realActivity = activity;
                            break;
                        }
                    }
                    //退回之后，满足的活动赠品对应的数量关系
                    Map<String, Integer> backAfterActivityNumMap = new HashMap<>();
                    //退回后满足的活动定义的赠品
                    if (null != realActivity) {
                        List<ActivityGift> activityGifts = realActivity.getActivityGifts();
                        for (ActivityGift activityGift : activityGifts) {
                            backAfterActivityNumMap.put(activityGift.getCommodityTerminalID(), activityGift.getNum());
                        }
                    }
                    
                    List<ReturnGift> returnGifts = new ArrayList<>();
                    for (Gift orderGift : orderGifts) {
                        ReturnGift returnGift = new ReturnGift();
                        returnGift.setReturnGiftID(Identities.uuid2());
                        returnGift.setReturnSalesID(returnSalesID);
                        returnGift.setGiftID(orderGift.getGiftID());
                        returnGift.setMaxReturnNum(orderGift.getNum());
                        returnGift.setModifyDate(modifyDate);
                        String terminalID = orderGift.getCommodityTerminalID();
                        returnGift.setCommodityTerminalID(terminalID);
                        Commodity commodity = iCommodityTmlService.findCommodityByCommodityTerminalID(terminalID);
                        returnGift.setCommodity(commodity);
                        int newRealNum = backAfterActivityNumMap.get(
                                orderGift.getCommodityTerminalID()) != null ? backAfterActivityNumMap.get(
                                orderGift.getCommodityTerminalID()) : 0;
                        //需要退回的
                        returnGift.setNum(orderGift.getNum() - newRealNum);
                        totalGiftNum = totalGiftNum + returnGift.getNum();
                        returnGifts.add(returnGift);
                    }
                    returnSales.setReturnGifts(returnGifts);
                }
            }
        }
        returnSales.setTotalPrice(orderTotalReturnPrice);
        returnSales.setCommodityNum(totalCommodityNum);
        returnSales.setGiftNum(totalGiftNum);
        
        returnSales.setReturner(order.getBuyer());
        returnSales.setCustomerUserID(order.getCustomerUserID());
        returnSales.setOrderID(order.getOrderID());
        logger.info(">>> 计算成功 " + returnSales);
        return new ReturnBean<>(ResultCode.SUCCESS, "计算成功", returnSales);
    }
    
    /**
     * 退货
     *
     * @param orderID
     * @param returnSales
     * @return
     */
    @Override
    public ReturnBean<ReturnSales> saveReturnSales(String orderID, ReturnSales returnSales) {
        
        //查询订单
        Order order = iSaleOrderService.findOne(orderID);
        ReturnBean<ReturnSales> errorResult = validateReturnSalesInfo(order);
        if (errorResult != null) {
            return errorResult;
        }
        
        returnSales.setReturnGifts(null);
        
        ReturnBean<ReturnSales> calcReturnSalesInfo = this.calcReturnSalesInfo(returnSales, order);
        if (ResultCode.SUCCESS.intValue() != calcReturnSalesInfo.getCode()) {
            return calcReturnSalesInfo;
        }
        
        returnSales = calcReturnSalesInfo.getResult();
        returnSales.setReturnSalesNO(generateReturnSalesNO());
        returnSales.setStatus(ReturnSalesStatus.草稿.getValue());
        returnSales.setOrderNo(order.getOrderNo());
        returnSales.setOrderType(order.getOrderType());
        
        returnSales = save(returnSales);
        
        return new ReturnBean<>(ResultCode.SUCCESS, "保存成功", returnSales);
    }
    
    /**
     * 编辑并保存退货信息
     *
     * @param returnSales
     * @return
     */
    @Override
    public ReturnBean<ReturnSales> editAndSaveReturnSales(ReturnSales returnSales) {
        //只有草稿和驳回的才允许保存
        ReturnSales dbObj = findOne(returnSales.getReturnSalesID());
        if (dbObj == null) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "returnSalesID不正确");
        }
        if (ReturnSalesStatus.草稿.getValue().intValue() != dbObj.getStatus()
                && ReturnSalesStatus.驳回.getValue().intValue() != dbObj.getStatus()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "此退货信息不能编辑保存");
        }
        Order order = iSaleOrderService.findOne(dbObj.getOrderID());
        ReturnBean<ReturnSales> calcReturnSalesInfo = this.calcReturnSalesInfo(returnSales, order);
        if (ResultCode.SUCCESS.intValue() != calcReturnSalesInfo.getCode()) {
            return calcReturnSalesInfo;
        }
        
        returnSales = calcReturnSalesInfo.getResult();
        returnSales.setStatus(ReturnSalesStatus.草稿.getValue());
        returnSales.setOrderNo(order.getOrderNo());
        returnSales.setOrderType(order.getOrderType());
        
        //删除原来的
        iReturnGiftService.deleteByReturnSalesID(returnSales.getReturnSalesID());
        iReturnSalesContentService.deleteByReturnSalesID(returnSales.getReturnSalesID());
        
        returnSales = save(returnSales);
        
        return new ReturnBean<>(ResultCode.SUCCESS, "保存成功", returnSales);
    }
    
    
    /**
     * 退货详情
     *
     * @param returnSalesID
     * @return
     */
    @Override
    public ReturnBean<ReturnSales> getReturnSales(String returnSalesID) {
        
        ReturnSales returnSales = findOne(returnSalesID);
        if (null == returnSales) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "returnSalesID不正确");
        }
        
        translateReturnSalesInfo(returnSales);
        
        return new ReturnBean<>(ResultCode.SUCCESS, "获取退货详情成功", returnSales);
    }
    
    @Override
    public void translateReturnSalesInfo(ReturnSales returnSales) {
        if (null != returnSales.getStatus()) {
            returnSales.setStatusStr(ReturnSalesStatus.getName(returnSales.getStatus()));
        }
        
        User user = iUserService.findOne(returnSales.getReturner());
        if (null != returnSales.getReturner()) {
            returnSales.setReturnUserName(user.getName());
            returnSales.setReturnUser(user);
        }
        
        if(null != returnSales.getOrderType()){
            returnSales.setOrderTypeStr(OrderType.getName(returnSales.getOrderType()));
        }
        
        //客户名称转换
        User one = iUserService.findOne(returnSales.getCustomerUserID());
        returnSales.setCustomerName(one.getName());
        
        List<ReturnSalesContent> returnSalesContents = returnSales.getReturnSalesContents();
        if (CollectionUtils.isNotEmpty(returnSalesContents)) {
            for (ReturnSalesContent returnSalesContent : returnSalesContents) {
                CommodityChannel commodityChannel = iCommodityChannelService.findOne(
                        returnSalesContent.getCommodityChannelID());
                buildReturnSalesContentCommodityInfo(returnSalesContent, commodityChannel);
                List<ReturnGift> returnGifts = returnSalesContent.getReturnGifts();
                if (CollectionUtils.isNotEmpty(returnGifts)) {
                    for (ReturnGift returnGift : returnGifts) {
                        Commodity commodity = iCommodityTmlService.findCommodityByCommodityTerminalID(
                                returnGift.getCommodityTerminalID());
                        returnGift.setCommodity(commodity);
                    }
                }
            }
        }
        
        List<ReturnGift> returnGifts = returnSales.getReturnGifts();
        if (CollectionUtils.isNotEmpty(returnGifts)) {
            for (ReturnGift returnGift : returnGifts) {
                Commodity commodity = iCommodityTmlService.findCommodityByCommodityTerminalID(
                        returnGift.getCommodityTerminalID());
                returnGift.setCommodity(commodity);
            }
        }
    }
    
    /**
     * 删除退货
     *
     * @param returnSalesID
     * @return
     */
    @Override
    public ReturnBean<ReturnSales> deleteReturnSales(String returnSalesID) {
        ReturnSales returnSales = findOne(returnSalesID);
        if (null == returnSales) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "returnSalesID不正确");
        }
        if (ReturnSalesStatus.草稿.getValue().intValue() != returnSales.getStatus()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "非草稿状态的退货单不能删除");
        }
        
        iReturnGiftService.deleteByReturnSalesID(returnSales.getReturnSalesID());
        iReturnSalesContentService.deleteByReturnSalesID(returnSales.getReturnSalesID());
        delete(returnSalesID);
        
        return new ReturnBean<>(ResultCode.SUCCESS, "删除成功");
    }
    
    /**
     * 取消退货
     *
     * @param returnSalesID
     * @return
     */
    @Override
    public ReturnBean<ReturnSales> cancelReturnSales(String returnSalesID) {
        //驳回的可以取消退货
        ReturnSales returnSales = findOne(returnSalesID);
        if (null == returnSales) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "returnSalesID不正确");
        }
        if (ReturnSalesStatus.驳回.getValue().intValue() != returnSales.getStatus()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "非驳回状态的退货单不能取消");
        }
        returnSales.setStatus(ReturnSalesStatus.取消.getValue());
        save(returnSales);
        return new ReturnBean<>(ResultCode.SUCCESS, "取消成功");
    }
    
    
    /**
     * 退货列表查询
     *
     * @param returnSalesNo
     * @param returner
     * @param customerName
     * @param status
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public ReturnBean<PageWrapper<ReturnSales>> getReturnSalesByCnd(
            String returner, String returnSalesNo, String customerName, Integer status, Long startTime, Long endTime,
            Integer pageNum, Integer pageSize) {
        Condition condition = new Condition();
        List<FilterCondition> filterConditions = new ArrayList<>();
        //returner
        ReturnBean<PageWrapper<ReturnSales>> page1 = getUserNameCondition(returner, "returner", filterConditions);
        if (page1 != null) {
            return page1;
        }
        //customerName
        ReturnBean<PageWrapper<ReturnSales>> page2 = getUserNameCondition(customerName, "customerUserID",
                filterConditions);
        if (page2 != null) {
            return page2;
        }
        
        if (!StringUtils.isEmpty(returnSalesNo)) {
            filterConditions.add(
                    new FilterCondition(returnSalesNo, "returnSalesNO", ConditionRelate.and.name(),
                            Operation.like.name(), 3));
        }
        if (status != null) {
            filterConditions.add(new FilterCondition(String.valueOf(status), "status", ConditionRelate.and.name(),
                    Operation.eq.name(), 4));
        }
        if (null != startTime) {
            filterConditions.add(new FilterCondition(String.valueOf(startTime), "returnSalesTime",
                    ConditionRelate.and.name(), Operation.ge.name(), 5));
        }
        if (null != endTime) {
            filterConditions.add(new FilterCondition(String.valueOf(endTime), "returnSalesTime",
                    ConditionRelate.and.name(), Operation.lt.name(), 6));
        }
        
        condition.setFilterCondition(filterConditions);
        
        condition = ConditionUtil.buildCondition(XiNiaoJSON.toJSONString(condition), ReturnSales.class).getResult();
        
        Pageable pageable = new PageRequest(pageNum - 1, pageSize, new Sort(Sort.Direction.DESC, "returnSalesTime"));
        Page<ReturnSales> page = findAll(condition.getSpecification(), pageable);
        
        List<ReturnSales> returnSalesList = page.getContent();
        if (CollectionUtils.isNotEmpty(returnSalesList)) {
            for (ReturnSales returnSales : returnSalesList) {
                translateReturnSalesInfo(returnSales);
            }
        }
        
        return new ReturnBean<>(ResultCode.SUCCESS, "查询成功", PageHelper.toPage(page));
    }
    
    private ReturnBean<PageWrapper<ReturnSales>> getUserNameCondition(
            String returner, String fieldName, List<FilterCondition> filterConditions) {
        if (!StringUtils.isEmpty(returner)) {
            if (returner.length() == 32 && !GeneralHelper.isChinese(returner)) {
                filterConditions.add(new FilterCondition(returner, fieldName, ConditionRelate.and.name(),
                        Operation.eq.name(), 1));
            } else {
                List<User> users = null;
                if (GeneralHelper.isChinese(returner)) {
                    users = iUserService.findByNameLike("%" + returner + "%");
                } else {
                    users = iUserService.findByNamePinYinLike(returner + "%");
                }
                if (CollectionUtils.isEmpty(users)) {
                    Page page = new PageImpl(new ArrayList());
                    return new ReturnBean<PageWrapper<ReturnSales>>(ResultCode.SUCCESS, "查询成功",
                            PageHelper.toPage(page));
                }
                List<String> userIDs = new ArrayList<>();
                for (User user : users) {
                    userIDs.add(user.getUserID());
                }
                filterConditions.add(new FilterCondition(userIDs, fieldName, ConditionRelate.and.name(),
                        Operation.in.name(), 1));
            }
        }
        return null;
    }
    
    /**
     * 退货入库
     *
     * @param returnSalesID
     * @return
     */
    @Override
    public ReturnBean<String> addReturnSalesInStock(String returnSalesID) {
        ReturnSales returnSales = findOne(returnSalesID);
        if (null == returnSales) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "returnSalesID不正确");
        }
        Order order = iSaleOrderService.findOne(returnSales.getOrderID());
        
        Map<String, Integer> terminalBackStockMap = new HashMap<>();
        for (ReturnSalesContent content : returnSales.getReturnSalesContents()) {
            CommodityTerminal commodityTerminal = iSaleOrderService.getCommodityTerminal(
                    String.valueOf(order.getOrderType()), content.getCommodityChannelID());
            if(!StringUtils.isEmpty(commodityTerminal.getConfigWarnMsg())){
                return new ReturnBean<>(ResultCode.ERROR_SERVICE, commodityTerminal.getConfigWarnMsg());
            }
            String commodityTerminalID = commodityTerminal.getCommodityTerminalID();
            if (terminalBackStockMap.containsKey(commodityTerminalID)) {
                terminalBackStockMap.put(commodityTerminalID,
                        terminalBackStockMap.get(commodityTerminalID) + content.getNum());
            } else {
                terminalBackStockMap.put(commodityTerminalID, content.getNum());
            }
            if (CollectionUtils.isNotEmpty(content.getReturnGifts())) {
                handleReturnGiftStockMap(content.getReturnGifts(), terminalBackStockMap);
            }
        }
        
        if (CollectionUtils.isNotEmpty(returnSales.getReturnGifts())) {
            handleReturnGiftStockMap(returnSales.getReturnGifts(), terminalBackStockMap);
        }
        
        //根据退回的商品和赠品数量进行入库操作
        long modifyDate = System.currentTimeMillis();
        // 入库
        InStock inStock = new InStock();
        inStock.setInStockType(InStockType.订单退货.getValue());
        inStock.setInStocker(returnSales.getReturner());
        //入库流水的单据号
        inStock.setProofID(returnSalesID);
        inStock.setWarehouseID(returnSales.getReturner());
        inStock.setModifyDate(modifyDate);
        //入库流水，包括正品和赠品
        List<InOutStockDetail> inOutStockDetails = new ArrayList<>();
        Iterator<Map.Entry<String, Integer>> iterator = terminalBackStockMap.entrySet().iterator();
        while (iterator.hasNext()) {
            OrderUtil.buildInOutStockDetail(modifyDate, inOutStockDetails, iterator.next().getKey(),
                    iterator.next().getValue());
        }
        inStock.setInOutStockDetails(inOutStockDetails);
        iStockService.addInStock(inStock);
        
        return new ReturnBean<>(ResultCode.SUCCESS, "退货入库成功");
    }
    
    private void handleReturnGiftStockMap(List<ReturnGift> returnGifts, Map<String, Integer> terminalBackStockMap) {
        for (ReturnGift returnGift : returnGifts) {
            String commodityTerminalID1 = returnGift.getCommodityTerminalID();
            if (terminalBackStockMap.containsKey(commodityTerminalID1)) {
                terminalBackStockMap.put(commodityTerminalID1,
                        terminalBackStockMap.get(commodityTerminalID1) + returnGift.getNum());
            } else {
                terminalBackStockMap.put(commodityTerminalID1, returnGift.getNum());
            }
        }
    }
}
